home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Environments / Small Eiffel 0.4.8 / lib_show / spread_illness.e < prev   
Text File  |  1997-04-13  |  7KB  |  321 lines

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. -- Originally written by Cyril ADRIAN and Antony LE LABOUSSE
  5. --
  6. class SPREAD_ILLNESS
  7.    -- To compile type command : compile SPREAD_ILLNESS make
  8.    --
  9.    -- Also try Optimised version adding options "-boost -O2"
  10.    --
  11. creation {ANY}
  12.    make
  13.    
  14. feature {NONE}
  15.    
  16.    world1, world2: ARRAY2[INTEGER];
  17.    
  18.    empty : INTEGER is 1;
  19.    
  20.    healthy : INTEGER is 0;
  21.    
  22.    di: ARRAY[INTEGER] is
  23.       once
  24.      Result := <<-1,-1,-1,0,1,1,1,0 >>
  25.       end;
  26.    
  27.    dj: ARRAY[INTEGER] is
  28.       once
  29.      Result := <<-1,0,1,1,1,0,-1,-1 >>
  30.       end;
  31.    
  32.    error_msg : STRING is "Error : do it again !%N"
  33.  
  34. feature {ANY}
  35.  
  36.    make is
  37.      -- Try to spreads an illness through a set of people.
  38.       local
  39.      day: INTEGER;
  40.      fed_up: BOOLEAN;
  41.       do
  42.      from  
  43.         day := 1;
  44.         first_day;
  45.      until
  46.         fed_up
  47.      loop
  48.         io.put_string("Day #");
  49.         io.put_integer(day);
  50.         io.put_new_line;
  51.         display;
  52.         io.put_string("Continue ? [y/n] ");
  53.         io.read_line;
  54.         io.last_string.to_lower;
  55.         fed_up := (io.last_string.first = 'n')
  56.         day := day + 1;
  57.         next_day
  58.      end;
  59.       end;
  60.  
  61. feature {ANY}
  62.    
  63.    first_day is
  64.      -- Create the world in the 1st day's state.
  65.       local
  66.      i, j, ill_state: INTEGER;
  67.      ok: BOOLEAN;
  68.       do
  69.      io.put_string("Default First World (y/n) ? ");
  70.      io.read_word;
  71.      if io.last_string.is_equal("y") then
  72.         !!world1.array2(
  73.           <<<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  74.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  75.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  76.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  77.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  78.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  79.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  80.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  81.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1>>,
  82.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  83.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  84.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  85.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  86.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  87.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  88.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  89.         <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  90.             <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>>>);
  91.      else
  92.         io.put_string("World size : ");
  93.         io.read_integer;
  94.         !!world1.make(1,io.last_integer,1,io.last_integer);
  95.         io.put_string("%Ne)mpty, i)ll with number of days, h)ealthy%N%N");
  96.         from  
  97.            i := world1.lower1
  98.         until
  99.            i > world1.upper1
  100.         loop
  101.            from  
  102.           j := world1.lower2
  103.            until
  104.           j > world1.upper2
  105.            loop
  106.           from
  107.              ok := false;
  108.           until
  109.              ok
  110.           loop
  111.              io.put_string("State of [");
  112.              io.put_integer(i);
  113.              io.put_character(',');
  114.              io.put_integer(j);
  115.              io.put_string("] : ");
  116.              io.read_word;
  117.              inspect 
  118.             io.last_string.first
  119.              when 'E','e' then
  120.             if io.last_string.count /= 1 then
  121.                io.put_string(error_msg)
  122.             else
  123.                world1.put(empty,i,j);
  124.                ok := true
  125.             end
  126.              when 'H','h' then
  127.             if io.last_string.count /= 1 then
  128.                io.put_string(error_msg)
  129.             else
  130.                world1.put(healthy,i,j);
  131.                ok := true
  132.             end
  133.              when 'I','i' then
  134.             ok := true;
  135.             io.read_integer;
  136.             ill_state := io.last_integer;
  137.             ill_state := ill_state.max(1);
  138.             ill_state := ill_state.min(4);
  139.             world1.put(- ill_state,i,j);
  140.              else
  141.             io.put_string(error_msg)
  142.              end;
  143.           end;
  144.           j := j + 1;
  145.            end;
  146.            i := i + 1;
  147.         end;
  148.      end;
  149.      world2 := clone(world1)
  150.       end;
  151.  
  152.    display is
  153.      -- Displays current `world2'.
  154.       local
  155.      i,j : INTEGER;
  156.       do
  157.      io.put_character('+');
  158.      io.put_character('-');
  159.      from  
  160.         i := world1.lower1
  161.      until
  162.         i > world1.upper1
  163.      loop
  164.         io.put_character('-');        
  165.         io.put_character('-');
  166.         i := i+1
  167.      end;
  168.      io.put_character('+');
  169.      io.put_new_line;
  170.      from  
  171.         i := world1.lower1
  172.      until
  173.         i > world1.upper1
  174.      loop
  175.         io.put_character('|');
  176.         io.put_character(' ');
  177.         from  
  178.            j := world1.lower2
  179.         until
  180.            j > world1.upper2
  181.         loop
  182.            inspect 
  183.           world2.item(i,j)
  184.            when empty then
  185.           io.put_character(' ')
  186.            when healthy then
  187.           io.put_character('O')
  188.            else
  189.           io.put_character((- world2.item(i,j)).digit)
  190.            end;
  191.            io.put_character(' ');
  192.            j := j+1
  193.         end;
  194.         io.put_character('|');
  195.         io.put_new_line;
  196.         i := i+1
  197.      end;
  198.      io.put_character('+');
  199.      io.put_character('-');
  200.      from  
  201.         i := world1.lower1
  202.      until
  203.         i > world1.upper1
  204.      loop
  205.         io.put_character('-');
  206.         io.put_character('-');
  207.         i := i+1
  208.      end;
  209.      io.put_character('+');
  210.      io.put_new_line;
  211.       end;
  212.    
  213.    next_day is
  214.      -- `world1' and `world2' are swapped. 
  215.       local
  216.      i,j: INTEGER;
  217.       do
  218.      world1.copy(world2);
  219.      from  
  220.         i := world1.lower1;
  221.      until
  222.         i > world1.upper1
  223.      loop
  224.         from  
  225.            j := world1.lower2;
  226.         until
  227.            j > world1.upper2
  228.         loop
  229.            inspect 
  230.           world1.item(i,j)
  231.            when empty then
  232.            when healthy then
  233.           spread(i,j);
  234.            else
  235.           cure_or_die(i,j);
  236.            end;
  237.            j := j + 1;
  238.         end;
  239.         i := i + 1;
  240.      end;
  241.       end;
  242.    
  243. feature {NONE}
  244.    
  245.    cure_or_die(i,j : INTEGER)  is
  246.      -- When ill, inspects if must be death or more ill or cured.
  247.       do
  248.      inspect      
  249.         - world1.item(i,j)
  250.      when 1 then 
  251.         world2.put(-2,i,j)
  252.      when 2 then 
  253.         die(i,j)
  254.      when 3 then 
  255.         world2.put(-4,i,j)
  256.      when 4 then 
  257.         world2.put(healthy,i,j)
  258.      end
  259.       end;
  260.  
  261.    die(i,j: INTEGER) is
  262.      -- When two days ill, dies or more ill ?
  263.       local
  264.      d,k:INTEGER;
  265.       do
  266.      from  
  267.         d := 1;
  268.      until
  269.         d > 8
  270.      loop
  271.         if v(i+di.item(d),j+dj.item(d)) <= -2 then
  272.            k := k+1;
  273.         end;
  274.         d := d+1;
  275.      end;
  276.      if k >= 4 then
  277.         world2.put(empty,i,j);
  278.      else
  279.         world2.put(-3,i,j);
  280.      end
  281.       end;
  282.    
  283.    spread(i,j: INTEGER) is
  284.      -- spread the illness ?
  285.       local
  286.      d: INTEGER;
  287.       do
  288.      from  
  289.         d := 1;
  290.      until
  291.         d = 9
  292.      loop
  293.         if ill(i + di @ d , j + dj @ d) then
  294.            world2.put(-1,i,j);
  295.            d := 9;
  296.         else
  297.            d := d+1;
  298.         end
  299.      end
  300.       end;
  301.    
  302.    ill(i,j: INTEGER): BOOLEAN is
  303.      -- Is there someone is ill at `i', `j'.
  304.       do
  305.      Result := (v(i,j) < 0)
  306.       end;
  307.    
  308.    v(i,j: INTEGER): INTEGER is
  309.      -- Gives `empty' when out of range or the
  310.      -- value in `world1'
  311.       do
  312.      if (world1.lower1 <= i and then i <= world1.upper1)
  313.         and (world1.lower2 <= j and then j <= world1.upper2) then
  314.         Result := world1.item(i,j)
  315.      else
  316.         Result := empty
  317.      end;
  318.       end;
  319.  
  320. end -- SPREAD_ILLNESS
  321.